#include <stdio.h>
#include <unistd.h>
#include <list>
#include <mutex>
#include <sstream>

class Object {
public:
    Object(const Object &o)
    {
        id = next_id++;
        printf("调用了拷贝构造函数, 用%d生成%d\n", o.id, id);
    }

    Object(Object &&o)
    {
        id = next_id++;
        printf("调用了移动构造函数, 用%d生成%d\n", o.id, id);
    }

    explicit Object(const char *)
    {
        id = next_id++;
        printf("调用了构造函数, 生成%d %p\n", id, this);
    }

    ~Object()
    {
        printf("%d调用了析构函数 %p\n", id, this);
    }

    void Func()
    {
        printf("%d调用了函数 %p\n", id, this);
    }

private:
    int id;
    static inline int next_id = 0;
};

#define WRAPPER(expr) printf("\033[31m" #expr "\033[0m\n"); expr

std::list<Object>& A(std::list<Object>& lists)
{
    WRAPPER(lists.push_back(Object("A")));
    WRAPPER(return lists);
}

int main()
{
    std::stringstream ss;
    ss << "cat /proc/" << getpid() << "/maps";
    system(ss.str().c_str());
    printf("push_back会调用构造函数构造临时对象然后用移动构造函数移到容器里去\n");
    WRAPPER({)
        WRAPPER(std::list<Object> lists);
        WRAPPER(lists.push_back(Object("1")));
        WRAPPER(lists.push_back(Object("2")));
        WRAPPER(lists.push_back(Object("3")));
        WRAPPER(lists.push_back(Object("4")));

        WRAPPER(auto&& v2 = A(lists));
        for (auto& i : v2) {
            i.Func();
        }
    WRAPPER(})

    printf("emplace_back会调用构造函数构造容器内对象\n");
    WRAPPER({)
        WRAPPER(std::list<Object> lists);
        WRAPPER(lists.emplace_back("1"));
        WRAPPER(lists.emplace_back("2"));
        WRAPPER(lists.emplace_back("3"));
        WRAPPER(lists.emplace_back("4"));

        WRAPPER(auto&& v2 = A(lists));
        for (auto& i : v2) {
            i.Func();
        }
    WRAPPER(})
    WRAPPER(return 0);
}
